home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / msoftapp.zip / LINEFILE.CPP < prev    next >
C/C++ Source or Header  |  1993-06-01  |  3KB  |  141 lines

  1. // linefile.cpp : Defines the class behaviors for the line file class.
  2.  
  3. #include "viewer.h"
  4.  
  5. IMPLEMENT_DYNAMIC(CLineFile, CStdioFile)
  6.  
  7. CLineFile::~CLineFile() {}
  8.  
  9. CLineFile::CLineFile() : CStdioFile()
  10.     {
  11.     m_lBeginLine = 0L;
  12.     }
  13.  
  14. CLineFile::CLineFile(const char* pszFileName, UINT nOpenFlags)
  15.         : CStdioFile(pszFileName, nOpenFlags)
  16.     {
  17.     m_lBeginLine = 0L;
  18.     }
  19.  
  20. //
  21. // assuming the current file offset points to the beginning of a line
  22. // read the next line, return offset of next line
  23. // also expand tabs to spaces
  24. const TABNUM  = 8;
  25.  
  26. LONG CLineFile::NextLine(char FAR* lpszArg, UINT nMax)
  27.     {
  28.     register char FAR * lpsz = lpszArg;
  29.     register UINT n = 0;
  30.  
  31.     m_lBeginLine = GetPosition();
  32.  
  33.     while(TRUE)
  34.         {
  35.         if(Read(lpsz, 1) != 1)
  36.             break;
  37.         n++;
  38.         if(*lpsz == '\n')
  39.             break;
  40.         if(*lpsz == '\r')
  41.             continue;
  42.         if(*lpsz == '\t')
  43.             for(*lpsz++ = ' '; (n % TABNUM) && (n < nMax); n++, lpsz++)
  44.                  *lpsz = ' ';
  45.         else
  46.             lpsz++;
  47.         if(n >= nMax)
  48.             break;
  49.         }
  50.     *lpsz = 0;
  51.     return GetPosition();
  52.     }
  53.  
  54. LONG CLineFile::SetBegin(LONG newBegin)
  55.     {
  56.     LONG save = m_lBeginLine;
  57.     m_lBeginLine = newBegin;
  58.     return save;
  59.     }
  60.  
  61. // read backwards a few(nLines) lines
  62.     // USE const
  63. #define GUESS       100L
  64. #define MAXLINES    200
  65.  
  66. LONG CLineFile::BackLines(char FAR* lpsz, UINT nMax, UINT nLines)
  67.     {
  68.     LONG    lines[MAXLINES];
  69.     LONG    guess;
  70.     register UINT i;
  71.  
  72.     if(m_lBeginLine == 0L)
  73.         {
  74.         Seek(0L, CFile::begin);
  75.         return NextLine(lpsz, nMax);
  76.         }
  77.  
  78.     if(nLines > MAXLINES)
  79.         nLines = MAXLINES;
  80.  
  81.     guess = m_lBeginLine - (GUESS * nLines);
  82.  
  83.     if(guess < 0L)
  84.         guess = 0L;
  85.     TRY
  86.         {
  87.         Seek(guess, CFile::begin);
  88.         }
  89.     CATCH(CFileException, e)
  90.         {
  91.         TRACE("Bad Seek in BackLines %ld\n", guess);
  92.         return -1;
  93.         }
  94.     END_CATCH
  95.  
  96.     if(guess != 0L)
  97.         ReadString(lpsz, nMax);       // skip forward to a line
  98.  
  99.     for(i = 0; i < nLines; i++)
  100.         lines[i] = -1L;
  101.  
  102.     while(TRUE)
  103.         {
  104.         for(i=MAXLINES-2; i > 0; i--)
  105.             lines[i] = lines[i-1];
  106.  
  107.         lines[0] = GetPosition();
  108.  
  109.         if(lines[0] >= m_lBeginLine)
  110.             break;
  111.  
  112.         ReadString(lpsz, nMax);       // skip forward a line
  113.         }
  114.  
  115.     while(lines[nLines] == -1L)
  116.         nLines--;
  117.  
  118.     Seek(lines[nLines], CFile::begin);
  119.     NextLine(lpsz, nMax);
  120.     m_lBeginLine = lines[nLines];
  121.     return m_lBeginLine;
  122.     }
  123.  
  124. // read a line near some file offset
  125. LONG CLineFile::LineNear(char FAR* lpsz, UINT nMax, LONG  lOffset)
  126.     {
  127.     TRY
  128.         {
  129.         Seek(lOffset, CFile::begin);
  130.         }
  131.     CATCH(CFileException, e)
  132.         {
  133.         TRACE("Bad Seek in LineNear %ld\n", lOffset);
  134.         return -1;
  135.         }
  136.     END_CATCH
  137.  
  138.     m_lBeginLine = NextLine(lpsz, nMax);    // find a real line
  139.     return BackLines(lpsz, nMax, 1);      // one just before it
  140.     }
  141.